#include "CSVFile.h"

/*
 *--------------------------------------------------------------------------------------
 *       Class:  CSVFile
 *      Method:  CSVFile
 * Description:  Contrói uma interface para um arquivo CSV passando seu nome e
 *               o tipo (input ou output)
 *--------------------------------------------------------------------------------------
 */
CSVFile::CSVFile(const char *filename, int type)
{
    this->type = type;

    // Input
    if(type == CSV_IN)
    {
        in = ifstreamPtr(new ifstream(filename));
        assert(in->is_open());

        buffer = ldoublePtr(new ldouble);
        getMore();
    }
    // Output
    else
    {
        out = ofstreamPtr(new ofstream(filename));
        assert(out->is_open());
        bol = true;
    }
}

/*
 *--------------------------------------------------------------------------------------
 *       Class:  CSVFile
 *      Method:  getMore
 * Description:  Recupera mais dados para o buffer
 *--------------------------------------------------------------------------------------
 */
void CSVFile::getMore()
{
    string line;

    while(getline(*in, line))
    {
        trim(line);
        if(line.empty())
            continue;

        vector<string> tokens;
        split(tokens, line, is_any_of(","), token_compress_on);

        for(uint i = 0; i < tokens.size(); i++)
        {
            trim(tokens[i]);
            assert(!tokens[i].empty());
            buffer->push_back(lexical_cast<double>(tokens[i]));
        }

        break;
    }
}

/*
 *--------------------------------------------------------------------------------------
 *       Class:  CSVFile
 *      Method:  has
 * Description:  Retorna verdadeiro se tiver dados a serem lidos
 *--------------------------------------------------------------------------------------
 */
bool CSVFile::has()
{
    return !buffer->empty();
}

/*
 *--------------------------------------------------------------------------------------
 *       Class:  CSVFile
 *      Method:  popDouble
 * Description:  Tira um valor double do buffer
 *--------------------------------------------------------------------------------------
 */
double CSVFile::pop()
{
    assert(has());

    double value = buffer->front();
    buffer->pop_front();

    if(buffer->empty())
        getMore();

    return value;
}

/*
 *--------------------------------------------------------------------------------------
 *       Class:  CSVFile
 *      Method:  writeComma
 * Description:  Escreve uma vírgula, se necessário
 *--------------------------------------------------------------------------------------
 */
void CSVFile::writeComma()
{
    if(!bol)
        (*out) << ",";
    bol = false;
}
